/**
 * @file midi2_ump.h
 * @brief MIDI 2.0 UMP (Universal MIDI Packet) 格式解析器
 * @details 实现MIDI 2.0 UMP消息的解析，支持32/64/128位消息类型
 * @version 1.0
 * @date 2025-11-04
 */

#ifndef __MIDI2_UMP_H__
#define __MIDI2_UMP_H__

#include <stdint.h>

/* ============================================================================
 * UMP消息大小定义
 * ============================================================================ */
#define UMP_SIZE_32BIT      4       /**< 32位UMP消息 (1个word) */
#define UMP_SIZE_64BIT      8       /**< 64位UMP消息 (2个word) */
#define UMP_SIZE_128BIT     16      /**< 128位UMP消息 (4个word) */

/* ============================================================================
 * UMP Message Type (MT) 定义
 * ============================================================================ */

/* UMP Message Type */
typedef enum
{
    UMP_MT_UTILITY          = 0x0,
    UMP_MT_SYSTEM           = 0x1,
    UMP_MT_MIDI1_CHANNEL    = 0x2,
    UMP_MT_DATA             = 0x3,
    UMP_MT_MIDI2_CHANNEL    = 0x4,
    UMP_MT_EXTENDED_DATA    = 0x5,
    UMP_MT_FLEX_DATA        = 0xD,
    UMP_MT_STREAM           = 0xF
} ump_message_type_e;

/* MIDI 2.0 Attribute Type */
typedef enum
{
    ATTR_NONE               = 0x00,
    ATTR_MANUFACTURER       = 0x01,
    ATTR_PROFILE            = 0x02,
    ATTR_PITCH              = 0x03
} midi2_attribute_type_e;

/* ============================================================================
 * MIDI 2.0状态字节定义 (用于MT4)
 * ============================================================================ */
#define MIDI2_STATUS_NOTE_OFF           0x80    /**< 音符关闭 */
#define MIDI2_STATUS_NOTE_ON            0x90    /**< 音符按下 */
#define MIDI2_STATUS_POLY_PRESSURE      0xA0    /**< 复音压力 */
#define MIDI2_STATUS_CONTROL_CHANGE     0xB0    /**< 控制变化 */
#define MIDI2_STATUS_PROGRAM_CHANGE     0xC0    /**< 程序变化 */
#define MIDI2_STATUS_CHANNEL_PRESSURE   0xD0    /**< 通道压力 */
#define MIDI2_STATUS_PITCH_BEND         0xE0    /**< 弯音轮 */
#define MIDI2_STATUS_PER_NOTE_MGMT      0xF0    /**< Per-Note管理 */

/* ============================================================================
 * 数据结构定义
 * ============================================================================ */

/**
 * @brief MIDI 2.0扩展消息结构
 * @details 包含MIDI 2.0消息的所有关键字段
 */
typedef struct
{
    uint8_t     mt;             /**< Message Type (UMP消息类型) */
    uint8_t     group;          /**< Group (0-15) */
    uint8_t     status;         /**< 状态字节 (含通道信息) */
    uint8_t     channel;        /**< MIDI通道 (0-15) */
    uint8_t     note;           /**< 音符号 (0-127) */
    uint16_t    velocity_16;    /**< 16位velocity (0-65535) */
    uint8_t     attr_type;      /**< 属性类型 (midi2_attribute_type_e) */
    uint16_t    attr_data;      /**< 属性数据 (16位) */
    uint32_t    controller_32;  /**< 32位控制器值 (用于CC消息) */
    uint16_t    data_16;        /**< 通用16位数据 (用于Pitch Bend等) */
} midi2_message_t;

/* ============================================================================
 * 函数声明
 * ============================================================================ */

/**
 * @brief 解析UMP数据包
 * @param data UMP数据缓冲区 (至少4字节对齐)
 * @param len 数据长度 (必须是4的倍数)
 * @param msg2 输出: MIDI 2.0消息结构指针
 * @return 0成功, -1失败
 *
 * @note 此函数自动识别MT2 (MIDI 1.0 in UMP) 和 MT4 (MIDI 2.0) 消息
 * @note 其他消息类型 (MT0/MT1/MT3/MT5/MTD/MTF) 暂不支持
 */
int midi2_ump_parse(uint8_t *data, uint8_t len, midi2_message_t *msg2);

/**
 * @brief 获取UMP消息大小
 * @param mt Message Type (ump_message_type_e)
 * @return 消息字节长度 (4/8/16), 未知类型返回0
 */
uint8_t midi2_ump_get_size(uint8_t mt);

/**
 * @brief 验证UMP数据包有效性
 * @param data UMP数据缓冲区
 * @param len 数据长度
 * @return 1有效, 0无效
 *
 * @note 检查长度是否为4的倍数且符合MT对应的消息大小
 */
int midi2_ump_validate(uint8_t *data, uint8_t len);

#endif /* __MIDI2_UMP_H__ */
